import { tuple } from '@gnlab/utils'
import { Popconfirm, Tooltip, Button, message, Table, Tag } from 'antd'
import { useStreams } from '@/lib/utils'
import services from '@/services'
import type { ExternalTag as QywxTag } from '@/services/contact-types'
import type { DescribeToTagsRule } from '@/services/features/describe-to-tags'
import EditModal from './Edit'
import './Content.module.less'

export default function Content() {
  const [corps] = useStreams(services.qywxs.corps)

  const [tagsMap, setTagsMap] = useState<Map<string, QywxTag>>(new Map())
  const loadTags = useCallback(async () => {
    // 子组件需要用到 GroupTag 因此这里调的是 getAllTags() 而不是 getCorpTags()
    const res = await services.externals.tags.getAllTags()
    if (res.success) {
      setTagsMap(new Map(res.data.map(tag => tuple(tag.id, tag))))
    } else {
      void message.warning('标签加载失败')
    }
  }, [])

  const [rules, setRules] = useState<DescribeToTagsRule[]>([])
  const [loading, setLoading] = useState(false)
  const loadRules = useCallback(async () => {
    setLoading(true)
    const res = await services.features.describeToTags.load()
    if (res.success) setRules(res.data)
    else void message.warning('描述转标签规则加载失败')
    setLoading(false)
    return res.success
  }, [])

  const [removing, setRemoving] = useState(false)
  const remove = useCallback(
    async (id: number) => {
      setRemoving(true)

      const res = await services.features.describeToTags.remove(id)
      if (res.success) void message.success('删除成功')
      else void message.warning(`删除失败：${res.error}`)

      await loadRules()

      setRemoving(false)
    },
    [loadRules],
  )

  const [editing, setEditing] = useState<false | true | DescribeToTagsRule>(false) // true: 新建  DescribeToTagsRule: 编辑
  const finishEdit = useCallback(() => {
    setEditing(false)
    void loadTags()
    void loadRules()
  }, [loadTags, loadRules])

  const blocking = loading || removing

  useEffect(() => {
    void loadTags()
    void loadRules()
  }, [loadTags, loadRules])

  const renderMatch = useCallback((rule: DescribeToTagsRule) => {
    return <>
      <span>$tag:</span>
      {rule.match}
      <span>:$</span>
    </>
  }, [])

  const renderTags = useCallback(
    (rule: DescribeToTagsRule) => {
      return rule.tagIds.map(id => {
        const tag = tagsMap.get(id)
        if (!tag) return null

        return <Tooltip key={id} title={`公司：${corps.get(tag.corpid) ?? ''}`}>
          <Tag>{tag.name}</Tag>
        </Tooltip>
      })
    },
    [corps, tagsMap],
  )

  const renderActions = useCallback(
    (rule: DescribeToTagsRule) => {
      return <>
        <Button type="link" onClick={() => setEditing(rule)}>
          修改
        </Button>
        <Popconfirm title="确定要删除此规则吗？" onConfirm={async () => remove(rule.id)}>
          <Button type="link" danger>
            删除
          </Button>
        </Popconfirm>
      </>
    },
    [remove],
  )

  return <div styleName="content">
    <header>
      <Button disabled={blocking} type="primary" onClick={() => setEditing(true)}>
        新建描述转标签规则
      </Button>
    </header>

    <Table<DescribeToTagsRule>
      rowKey="id"
      dataSource={rules}
      scroll={{ y: 300 }}
      pagination={false}
      loading={blocking}
    >
      <Table.Column<DescribeToTagsRule>
        title="描述内容"
        key="match"
        width={180}
        styleName="match"
        render={renderMatch}
      />
      <Table.Column<DescribeToTagsRule>
        title="标签"
        key="tags"
        styleName="tags"
        render={renderTags}
      />
      <Table.Column<DescribeToTagsRule>
        title="操作"
        key="actions"
        width={140}
        styleName="actions"
        render={renderActions}
      />
    </Table>

    <EditModal editing={editing} onFinish={finishEdit} tagsMap={tagsMap} corps={corps} />
  </div>
}
